/**
 * File Comment: Edit toString, 1 audit rule disabled

 */
package edu.gatech.oad.project.operations.users;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


import edu.gatech.oad.project.coordinator.Office;
import edu.gatech.oad.project.operations.data.Appointment;
import edu.gatech.oad.project.operations.data.MedicalHistory;
import edu.gatech.oad.project.operations.data.PatientInformation;
import edu.gatech.oad.project.operations.scheduling.Schedule;

/**
 * Java Representation of a patient.
 * Stores their medical history
 * and general information.
 * 
 * @author Group 17
 * @version 3.0
 */
public class Patient extends User {
    
    /**
     * 
     */
    private static final long serialVersionUID = -4449587765838735006L;

    /**
     * Field info, stores patient information
     */
    private PatientInformation info; // $codepro.audit.disable variableShouldBeFinal
    
    /**
     * Field myLogger: holds the logget for the office file
     */
    private static final Logger MYLOGGER = Logger.getLogger("edu.gatech." +
            "oad.project.operations.users");
    
    /**
     * Default constructor for patient.
     * 
     * @param name of the patient
     * @param id of the patient
     * @param s main scheduler
     */
    public Patient(String name, int id, Schedule s) {
        this(name, id);
        this.scheduler = s;
        MYLOGGER.finest("Patient with name, id, and schedule created");
    }

    /**
     * Patient constructor. Makes
     * an empty medical history and sets 
     * a pointer to the current
     * scheduler in the system
     * 
     * @param name name of the patient
     * @param id of the patient
     * @param s current working scheduler
     * @param i the patients personal data
     */
    public Patient(String name, int id, Schedule s, PatientInformation i) {
        this(name, id);
        this.scheduler = s;
        this.info = i;
        MYLOGGER.finest("Patient with name, id, schedule, and info created");
    }
    
    /**
     * Constructor for patient that only
     * takes in a name and id. For this case,
     * it creates an empty patient information
     * and medical history. has no pointer to
     * scheduler
     * 
     * @param name of the patient
     * @param id of the patient
     */
    public Patient(String name, int id){
        super(name, id);//constructor chaining--Jon C.
        this.info = new PatientInformation();
        this.history = new MedicalHistory(); 
        this.scheduler = null;
        
        MYLOGGER.addHandler(Office.FILEHANDLER);
        MYLOGGER.setLevel(Level.ALL);
        MYLOGGER.finest("Patient with name, id created");
    }
 
    /**
     * Adds a pending appointment to the scheduler
     * if doctor is free at the given time and
     * adds an appointment to the internal medical
     * history. NOTE: remove the appointment from
     * internal data struct if the appointment gets
     * rejected.
     * 
     * @param date the date desired
     * @param time the time desired
     * @param d the doctor desired
     * @param reason the reason for the appointment
     */
    @Override
    public void makeAppointment(int date, int time, Doctor d, String reason){
        final Appointment app = new Appointment(0, date, time, d, this, reason);
        
        if(this.scheduler.isAvailable(app)){
            MYLOGGER.info("Appointment is availabe and added: " + app.toString());
            this.scheduler.add(app);
            this.history.add(app);
        }
        else{
            MYLOGGER.info("Appointment is not available: " + app.toString());
        }
    }

    /**
     * @param app the appointment to remove
     */
    public void removeAppointment(Appointment app){
        
        this.scheduler.cancelApp(app);
        this.history.removeAppointment(app);
    }
    
    /** 
     * Returns the name of the patient as a string
     * 
     * @return String the name of the patient
     */
    @Override
    public String toString(){
        return this.getName();
    }
 
    /**
     * Gets the list of appointments in the 
     * patient's medical history
     * 
     * @return List of appointments
     */
    public List<Appointment> getPastAppointments(){
        final List<Appointment> apps = this.history.getAppointments();
        
        if(apps != null){
            MYLOGGER.finest("Found list of appointments for: " + this.name);
        }
        else{
            MYLOGGER.finest("Did not find any appointments for: " + this.name);
        }
        return apps;
    }
 
    /**
     * Looks through medical history and finds an
     * appointment.
     *  
     * @param p the appointment to find
     * @param id search via id or date
     * @return the appointment
     */
    public Appointment getAppointment(Appointment p, boolean id) {
        final Appointment temp;
        if (id) {
            temp = this.history.find(p);
        }
        else {
            temp = this.history.findByDate(p);
        }
        
        if(temp != null){
            MYLOGGER.info("Found Appointment for: " + this.name);
        }
        else{
            MYLOGGER.info("No appointment exists for: " + this.name);
        }
        return temp;
    }
 
    /**
     * Returns the patients personal information
     * and medical information
     * 
     * @return PatientInformation
     */
    public PatientInformation getInformation(){
        return this.info;
    }
 
    /**
     * Updates the old patient information with the
     * new information.
     * 
     * @param newInfo new patient info
     */
    public void updateInformation(PatientInformation newInfo){
        MYLOGGER.finest("begin patient information update sequence");
        this.info.update(newInfo);
    }
}
